package com.tencent.wxcloudrun.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.tencent.wxcloudrun.config.ApiResponse;
import com.tencent.wxcloudrun.model.KUser;
import com.tencent.wxcloudrun.service.KUserService;
import com.tencent.wxcloudrun.service.WxLoginService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.*;

/**
 * @Author yuyongkang
 * @Date 2025/9/18 14:01
 */
@Service
@Slf4j
public class WxLoginServiceImpl implements WxLoginService {

    @Value("${wechat.appid}")
    private String appid;

    @Value("${wechat.secret}")
    private String secret;

    @Value("${wechat.login-url}")
    private String loginUrl;

    @Value("${jwt.secret}")
    private String jwtSecret;

    @Value("${jwt.expire}")
    private long jwtExpire;

    private final RestTemplate restTemplate = new RestTemplate();

    @Resource
    private KUserService kUserService;


    @Override
    public ApiResponse wxLogin(Map<String, Object> params) {
        String code = (String) params.get("code");
        if (code == null || code.isEmpty()) {
            return ApiResponse.error("code不能为空");
        }

        // 1. 调用微信接口，用code换取openid和session_key
        String url = String.format(
                "%s?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                loginUrl, appid, secret, code
        );

        String responseString = restTemplate.getForObject(url, String.class);
        log.info("wx-login-api-response: {}", responseString);
        JSONObject wxLoginUserInfo = JSONObject.parseObject(responseString);
        if (wxLoginUserInfo == null || wxLoginUserInfo.getString("openid") == null || wxLoginUserInfo.getString("session_key") == null) {
            return ApiResponse.error("微信登录失败");
        }
        log.info("wx-login-api-response: {}", wxLoginUserInfo.getString("openid"));

        // 2. 生成自定义token（用JWT关联openid）
        String token = generateToken(wxLoginUserInfo.getString("openid"));

        // 3. 可选：将openid存入数据库（首次登录创建用户）
         kUserService.createOrUpdateUser(wxLoginUserInfo.getString("openid"));

        return ApiResponse.ok(token);
    }

    @Override
    public ApiResponse updateInfo(Map<String, Object> params) {
        String token = (String) params.get("token");
        if (token == null || token.isEmpty()) {
            return ApiResponse.error("token不能为空");
        }

        try {
            // 通过token获取openid
            String openid = parseToken(token);
            if (openid == null || openid.isEmpty()) {
                return ApiResponse.error("无效的token");
            }

            // 你可以在这里根据openid获取用户详细信息或更新用户信息
            // 例如：
            List<KUser> kUsers = kUserService.selectUserListByOpenid(openid);
            if (kUsers.size() > 0) {
                KUser kUser = kUsers.get(0);
                kUser.setNickname((String) params.get("nickname"));
                kUser.setAvatarUrl((String) params.get("avatarUrl"));
                kUser.setGender((String)params.get("gender"));
                kUserService.updateUserInfo(kUser);
            }

            // 返回用户信息
            Map<String, Object> result = new HashMap<>();
            result.put("openid", openid);
            // 可以添加更多用户信息
            return ApiResponse.ok(result);
        } catch (Exception e) {
            log.error("解析token失败", e);
            return ApiResponse.error("token解析失败: " + e.getMessage());
        }
    }


    // 从JWT token中解析openid（使用新版API）
    private String parseToken(String token) {
        if (token == null || token.isEmpty()) {
            return null;
        }

        try {
            // 创建密钥
            SecretKey key = Keys.hmacShaKeyFor(jwtSecret.getBytes(StandardCharsets.UTF_8));

            // 解析token并获取subject(openid)
            String openid = Jwts.parserBuilder()
                    .setSigningKey(key)
                    .build()
                    .parseClaimsJws(token)
                    .getBody()
                    .getSubject();

            return openid;
        } catch (Exception e) {
            log.error("解析token失败: {}", e.getMessage());
            return null;
        }
    }


    // 生成JWT token
    private String generateToken(String openid) {
        Date expiration = new Date(System.currentTimeMillis() + jwtExpire * 1000);

        // 验证并处理密钥
        byte[] keyBytes;
        if (jwtSecret == null || jwtSecret.isEmpty()) {
            throw new IllegalArgumentException("JWT secret cannot be null or empty");
        }

        try {
            // 尝试作为Base64解码
            keyBytes = Base64.getDecoder().decode(jwtSecret);
        } catch (IllegalArgumentException e) {
            // 如果不是Base64，直接使用UTF-8字节
            keyBytes = jwtSecret.getBytes(StandardCharsets.UTF_8);
        }

        // 确保密钥长度至少为256位(32字节)
        if (keyBytes.length < 32) {
            // 如果太短，使用SHA-256哈希扩展到合适长度
            try {
                MessageDigest digest = MessageDigest.getInstance("SHA-256");
                keyBytes = digest.digest(keyBytes);
            } catch (NoSuchAlgorithmException ex) {
                // 退回到简单填充
                keyBytes = Arrays.copyOf(keyBytes, 32);
            }
        }

        return Jwts.builder()
                .setSubject(openid) // 将openid存入token
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, keyBytes)
                .compact();
    }
    private static String generateSecureJwtSecret() {
        // 生成一个32字节(256位)的安全密钥
        byte[] keyBytes = new byte[32];
        new SecureRandom().nextBytes(keyBytes);
        return Base64.getEncoder().encodeToString(keyBytes);
    }

    public static void main(String[] args) {

        System.out.println(generateSecureJwtSecret());
    }

    // 微信登录接口返回的参数封装
    static class WechatLoginResponse {
        private String openid; // 用户唯一标识
        private String session_key; // 会话密钥（需保密）
        private String unionid; // 多账号关联时使用
        private Integer errcode;
        private String errmsg;

        // getters and setters
        public String getOpenid() { return openid; }
        public void setOpenid(String openid) { this.openid = openid; }
        // 其他字段的getter/setter省略
    }
}
